<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>01-对闭包的理解</title>
</head>

<body>
    <script>
        /*
            产生条件：
                1、两个函数相互嵌套
                2、内部函数访问外部函数的局部变量
                3、返不返回内部函数都会产生闭包
                    3.1.返回内部函数会产生一个有用的闭包
                    3.2.不返回内部函数也会产生闭包，只不过是个没用的闭包，闭包产生一瞬间就销毁了
            闭包作用：
                1、延长变量的声明周期
                2、外部函数可以访问内部函数局部变量
            闭包的真正产生时机：
                外部函数调用,执行内部函数定义
            什么是闭包：
               官方解释： 闭包（closure）是一个函数以及其捆绑的周边环境状态（lexical environment，词法环境）的引用的组合
               民间解释： 闭包就是一个引用关系，根据内部函数所使用外部函数的局部变量所形成的一个集合（保存的是内部函数所使用的外部函数的所有变量）
            闭包的缺点：
                闭包会延长变量的声明周期，这样会把内部函数一直保存在内存里不会被垃圾回收机制回收释放，如果闭包使用的过多，那内存里保存的数据就越多，
                    数据越多就会造成内存泄漏，内存泄漏过多就会造成内存溢出，内存溢出会造成浏览器卡顿，程序宕机

                内存泄漏:  程序运行时分配出去的内存空间，当程序运行完不能被及时的回收释放，就会造成内存泄漏

                内存溢出: 程序运行所需要的内存空间，电脑内存可使用的内存空间不满足程序运行所需要的内存空间时就会造成内存溢出

            怎么解决闭包带来的问题：
                断开内部函数的地址引用
            闭包的使用场景：
                1、React里的高阶组件
                2、vue里的数据劫持用到了闭包
                3、项目里做删除的操作，用到了闭包

        */
        function wrap() {
            debugger
            var a = 10
            // function inner() {
            //     a++
            //     return a
            // }
            var inner = function () {
                a++;
                return a
            }
            return inner
        }
        // 只要有外部变量对我们的对象有地址引用，那该对象就不能当成是垃圾对象
        let result = wrap()
        // 断开内部函数的地址引用
        result = null


    </script>
</body>

</html>